package com.lovely602.ai.alibaba.controller.chat;


import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.cloud.ai.memory.jdbc.MysqlChatMemoryRepository;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/**
 *
 * @author lizhixing
 */
@RestController
@RequestMapping(value = "/chat/client")
public class ChatClientController {


    private static final String DEFAULT_PROMPT = """
            你是一个博学的智能聊天助手，请根据用户提问回答！
            """;

    private final ChatClient chatClient;

    public ChatClientController(ChatClient.Builder builder, JdbcTemplate jdbcTemplate) {

        // 聊天记忆存储库
        ChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder()
                .jdbcTemplate(jdbcTemplate)
                .build();

        // 消息窗口聊天记忆
        MessageWindowChatMemory chatMemory = MessageWindowChatMemory
                .builder()
                .chatMemoryRepository(chatMemoryRepository)
                .maxMessages(50) // 最多记忆50条消息
                .build();

        // 消息聊天记忆顾问
        MessageChatMemoryAdvisor messageChatMemoryAdvisor = MessageChatMemoryAdvisor
                .builder(chatMemory)
                .build();

        this.chatClient = builder
                .defaultSystem(DEFAULT_PROMPT)
                // 实现 Chat Memory 的 Advisor
                // 在使用 Chat Memory 时，需要指定对话 ID，以便 Spring AI 处理上下文。
                .defaultAdvisors(messageChatMemoryAdvisor)
                // 实现 Logger 的 Advisor
                .defaultAdvisors(
                        new SimpleLoggerAdvisor()
                )
                // 设置 ChatClient 中 ChatModel 的 Options 参数
                .defaultOptions(
                        DashScopeChatOptions.builder()
                                .withTopP(0.7)
                                .build()
                )
                .build();
    }

    /**
     * 普通聊天
     */
    @GetMapping(value = "/call")
    public String chat(@RequestParam(value = "msg", required = true) String msg) {
        return chatClient.prompt(msg).call().content();
    }

    /**
     * 流式聊天
     */
    @GetMapping(value = "/stream", produces = "text/html;charset=UTF-8")
    public Flux<String> stream(@RequestParam(value = "msg", required = true) String msg) {
        return chatClient.prompt(msg).stream().content();
    }

    /**
     * 聊天记忆
     */
    @GetMapping("/memory")
    public String memory(@RequestParam(value = "msg") String msg,
                         @RequestParam(value = "chatId", defaultValue = "1") String chatId) {

        return chatClient.prompt(msg)
                .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
                .call().content();
    }

}
